/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Persistence;

import java.io.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import servidorped.User;

/**
 *
 * @author Micosil
 */
public class ConversationMemory implements ConversationPersistence {

    String pathToLogHome;

    public ConversationMemory(String pathToConfig) {
        BufferedReader pathReader = null;
        try {
            pathReader = new BufferedReader(new FileReader(new File(pathToConfig)));
            pathReader.readLine();        
            pathToLogHome = pathReader.readLine();
        } catch (IOException ex) {
            pathToLogHome = "logs";
        }
        File path = new File(pathToLogHome);        
        if (!path.exists()) {
            path.mkdir();
        }

    }

    @Override
    public void storeConversation(List<User> usersInConvo, List<String> conversation, Date conversationStart) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(conversationStart);
        storeUsers(cal, usersInConvo);
        storeLines(cal, conversation);


    }

    private void storeUsers(Calendar conversationStart, List<User> usersInConvo) {

        File userFile = new File(pathToLogHome + "/Users_" + getDateAsString(conversationStart));
        try {
            userFile.createNewFile();
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not create file " + userFile.getPath() + " but could not determine if it was created either.", ex);
        }

        BufferedWriter userWriter = null;
        try {
            userWriter = new BufferedWriter(new FileWriter(userFile));
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not open writing stream to file " + userFile.getPath(), ex);
        }
        for (User user : usersInConvo) {
            try {
                userWriter.write(user.getUserName() + "\n");
            } catch (IOException ex) {
                Logger.getGlobal().log(Level.SEVERE, "Error writing to file " + userFile.getPath(), ex);
            }
        }
        try {
            userWriter.flush();
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not transfer data from buffer to file " + userFile.getPath(), ex);
        }
        try {
            if (userWriter != null)
            userWriter.close();
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not close writing stream to " + userFile.getPath() + " properly.", ex);
        }
    }

    private boolean fileContains(String string, File file) {
        BufferedReader finder;
        try {
            finder = new BufferedReader(new FileReader(file));
        } catch (FileNotFoundException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not find file " + file.getPath() + ". This is a bug that should not happen.", ex);
            return false;
        }
        String oneLine;
        try {
            while ((oneLine = finder.readLine()) != null) {
                if (oneLine.contains(string)) {
                    return true;
                }
            }
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Error while reading from file {0}", file.getPath());
            return false;
        } finally {
            try {
                if (finder != null)
                finder.close();
            } catch (IOException ex) {
                Logger.getGlobal().log(Level.SEVERE, null, ex);
            }
        }
        return false;
    }

    private String getDateAsString(Calendar cur) {
        return Integer.toString(cur.get(Calendar.YEAR)) + "-" + Integer.toString(cur.get(Calendar.MONTH)) + "-" + Integer.toString(cur.get(Calendar.DAY_OF_MONTH)) + "_" + Integer.toString(cur.get(Calendar.HOUR_OF_DAY)) + "-" + Integer.toString(cur.get(Calendar.MINUTE)) + "-" + Integer.toString(cur.get(Calendar.SECOND));
    }

    private void storeLines(Calendar cal, List<String> conversation) {
        File textFile = new File(pathToLogHome + "/History_" + getDateAsString(cal));
        try {
            textFile.createNewFile();
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not create file " + textFile.getPath() + " but could not determine if it was created either.", ex);
        }

        BufferedWriter textWriter = null;
        try {
            textWriter = new BufferedWriter(new FileWriter(textFile));
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not open writing stream to file " + textFile.getPath(), ex);
        }
        for (String string : conversation) {
            try {
                textWriter.write(string + "\n");
            } catch (IOException ex) {
                Logger.getGlobal().log(Level.SEVERE, "Error writing to file " + textFile.getPath(), ex);
            }
        }
        try {
            textWriter.flush();
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not transfer data from buffer to file " + textFile.getPath(), ex);
        }
        try {
            if (textWriter != null)
            textWriter.close();
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not close writing stream to " + textFile.getPath() + " properly.", ex);
        }

    }

    @Override
    public List<String> findConversationsByUser(String userName) {
        File[] filesInFolder = new File(pathToLogHome).listFiles();
        List<String> conversationsFound = new ArrayList();
        for (File oneFile : filesInFolder) {
            if (oneFile.getName().startsWith("Users_") && fileContains(userName, oneFile)) {
                conversationsFound.add(oneFile.getName().substring(oneFile.getName().indexOf("_") + 1));
            }
        }
        return conversationsFound;
    }

    @Override
    public boolean isUserInConversation(String conversationDate, String userName) {
        File usersFile = new File(pathToLogHome + "/Users_" + conversationDate);
        BufferedReader reader;
        try {
            reader = new BufferedReader(new FileReader(usersFile));
        } catch (FileNotFoundException ex) {
            Logger.getGlobal().log(Level.SEVERE, "File " + usersFile.getPath() + " should exist, but does not.", ex);
            return false;
        }
        String oneString;
        boolean result = false;
        try {
            while ((oneString = reader.readLine()) != null) {
                if (oneString.equals(userName)) {
                    result = true;
                    break;
                }
            }
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "File " + usersFile.getPath() + " could not be read.", ex);
        } finally {
            try {
                if (reader != null)
                reader.close();
            } catch (IOException ex) {
                Logger.getGlobal().log(Level.SEVERE, null, ex);
            }
        }
        return result;
    }
    
    @Override
    public List<String> getAllConversations(){
        File[] filesInFolder = new File(pathToLogHome).listFiles();
        List<String> conversationsFound = new ArrayList();
        for (File oneFile : filesInFolder) {
            if (oneFile.getName().startsWith("History_")) {
                conversationsFound.add(oneFile.getName().substring(oneFile.getName().indexOf("_") + 1));
            }
        }
        return conversationsFound;        
    }

    @Override
    public boolean conversationExists(String conversationDate) {
        File usersFile = new File(pathToLogHome + "/Users_" + conversationDate);
        File textFile = new File(pathToLogHome + "/History_" + conversationDate);
        return (usersFile.exists() && textFile.exists());

    }

    @Override
    public List<String> retrieveConversation(String conversationDate) {
        File textFile = new File(pathToLogHome + "/History_" + conversationDate);
        BufferedReader textReader;
        try {
            textReader = new BufferedReader(new FileReader(textFile));
        } catch (FileNotFoundException ex) {
            Logger.getGlobal().log(Level.SEVERE, "File " + textFile.getPath() + " should exist, but does not.", ex);
            return null;
        }
        List<String> returnValue = new ArrayList();
        String oneLine;
        try {
            while ((oneLine = textReader.readLine()) != null) {
                returnValue.add(oneLine);
            }
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "File " + textFile.getPath() + " could not be read.", ex);
            return null;
        } finally {
            try {
                if (textReader != null)
                textReader.close();
            } catch (IOException ex) {
                Logger.getGlobal().log(Level.SEVERE, null, ex);
            }
        }
        return returnValue;

    }
}
